package test

import (
	"encoding/json"
	"log"
	"time"

	"github.com/gogf/gf/util/gconv"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"idoone.cc/idoonego/db/sql"
	"idoone.cc/idoonego/util"
)

// MysqlDB MysqlDB
var mydb *gorm.DB

// sys_user 用户信息
type SysUser struct {
	ID         string       `gorm:"column:id;type:varchar(32);primary_key" json:"id"`
	NickName   string       `gorm:"column:nickname;type:varchar(50)" json:"nickname"`
	UserName   string       `gorm:"column:username;type:varchar(50)" json:"username"`
	State      string       `gorm:"column:state;type:char(1)" json:"state"`
	Sort       int32        `gorm:"type:bigint" json:"sort"`
	CreateTime sql.DateTime `gorm:"type:datetime" json:"create_time"`
	UpdateTime sql.DateTime `gorm:"type:datetime" json:"update_time"`
	Data1      sql.Bytes    `gorm:"type:text" json:"data1"`
	Data2      sql.Bytes    `gorm:"type:text" json:"data2"`
	Detail     string       `gorm:"type:text" json:"detail"`
	otherInfo  string
}

// UserInfo 用户信息
type UserInfo struct {
	ID         string       `json:"id"`
	NickName   string       `json:"nickname"`
	UserName   string       `json:"username"`
	State      string       `json:"state"`
	Sort       int32        `json:"sort"`
	CreateTime sql.DateTime `json:"create_time"`
	UpdateTime sql.DateTime `json:"update_time"`
	Data1      sql.Bytes    `json:"data1"`
	Data2      sql.Bytes    `json:"data2"`
	Detail     string       `json:"detail"`
	otherInfo  string
}

func TestDB() {
	InitDB("wechat_mmtls:x0kq441y6000207wh0lnk0@tcp(127.0.0.1:3306)/wechat_mmtls?charset=utf8mb4&parseTime=true")

	log.Println("------------- SaveSysUser")
	ID := "wxid_usoyrwp9pb8l22"
	SaveSysUser(ID)
	SaveSysUser("2")
	SaveSysUser("3")

	log.Println("------------- UpdateSysUserByMap")
	UpdateSysUserByMap(ID, "0", "2")

	log.Println("------------- SelectByModel")
	sysUser := SelectByModel(ID)
	jsonUser, err := json.Marshal(sysUser)
	log.Println(err)
	log.Printf("SelectByModel: %+v", sysUser)
	log.Printf("SelectByModel: %+v", string(jsonUser))
	log.Printf("SelectByModel: %+v", gconv.String(sysUser))

	log.Println("------------- UpdateSysUserByModel")
	UpdateSysUserByModel(ID, "0", "3")

	log.Println("------------- SelectByWhere")
	sysUser = SelectByWhere(ID)
	jsonUser, err = json.Marshal(sysUser)
	log.Println(err)
	log.Printf("SelectByWhere: %+v", sysUser)
	log.Printf("SelectByWhere: %+v", string(jsonUser))
	log.Printf("SelectByWhere: %+v", gconv.String(sysUser))

	log.Println("------------- SimpleCopyFields")
	userInfo := &UserInfo{}
	util.SimpleCopyFields(userInfo, sysUser)
	jsonUser, err = json.Marshal(userInfo)
	log.Println(err)
	log.Printf("SimpleCopyFields: %+v", userInfo)
	log.Printf("SimpleCopyFields: %+v", string(jsonUser))
	log.Printf("SimpleCopyFields: %+v", gconv.String(userInfo))

	SelectByModel("null")
	SelectByWhere("null")
	SelectByModel("not_found")
	SelectByWhere("not_found")
	SelectListByWhere()
}

// InitDB 初始化数据库
func InitDB(conn_url string) {
	db, err := gorm.Open("mysql", conn_url)
	if err != nil {
		log.Panic(err)
		return
	}
	db.DB().SetConnMaxLifetime(time.Minute * 15)
	// 设置连接池中的最大闲置连接数
	db.DB().SetMaxIdleConns(10)
	// 设置数据库的最大连接数量
	db.DB().SetMaxOpenConns(200)

	db.SingularTable(true)
	db.AutoMigrate(&SysUser{}) // 自动建表
	db.LogMode(true)
	mydb = db
}

// SaveSysUser 新增
func SaveSysUser(id string) {
	user := &SysUser{
		ID:         id,
		NickName:   id,
		State:      "1",
		CreateTime: sql.DateTime{Time: time.Now()},
		Data1:      []byte("hello world"),
		Detail:     "0"}
	mydb.Save(user)
}

// SelectByModel 查找
func SelectByModel(id string) *SysUser {
	sysUser := &SysUser{ID: id}
	if err := mydb.First(sysUser).Error; err != nil {
		log.Println(err)
		return nil
	}
	return sysUser
}

// SelectByWhere 查找
func SelectByWhere(id string) *SysUser {
	var sysUser SysUser
	if err := mydb.Where("id=?", id).First(&sysUser).Error; err != nil {
		log.Println(err)
		return nil
	}
	return &sysUser
}

// SelectByWhere 查找
func SelectListByWhere() {
	sysUsers := make([]SysUser, 1)

	if err := mydb.Find(&sysUsers).Error; err != nil {
		log.Println(err)
		return
	}
	log.Println(sysUsers)
}

// UpdateSysUserByMap 更新
func UpdateSysUserByMap(id string, state string, detail string) {
	v := SelectByWhere(id)
	if v != nil {
		data := make(map[string]interface{})
		data["State"] = state
		data["Detail"] = detail
		where := &SysUser{ID: id}
		mydb.Model(where).Update(data)
	}
}

// UpdateSysUserByModel 更新
func UpdateSysUserByModel(id string, state string, detail string) {
	v := SelectByModel(id)
	if v != nil {
		data := &SysUser{State: state, Detail: detail}
		where := &SysUser{ID: id}
		mydb.Model(where).Update(data)
	}
}
